package generation.methods;
import moplayer.MoMidiUtils;

public class BasicMarkov {
	
	// A map for our musical pitches
	int[] map = { 67, 69, 60, 62, 64 };
	// A multidimensional array representing our markov matrix
	double[][] markovMatrix = { 
			{ 0.5,  0.0,  0.5,  0.0,  0.0 },
			{ 0.0,  0.25, 0.25, 0.25, 0.25 },
			{ 0.25, 0.25, 0.25, 0.25, 0.0 },
			{ 0.5,  0.0,  0.5,  0.0,  0.0 }, 
			{ 1.0/3.0, 0.0,  0.0,  1.0/3.0, 1.0/3.0 } 
	};
	// The seed for generating output
	int seed; // checking that our map says 64 is at index 2
	// The output as an index value
	int output; // there are no outputs yet
	boolean isFirstTime;
	
	public BasicMarkov() {
		this.isFirstTime = true;
		this.seed = 2;
		this.output = 0;
	}
	
	public BasicMarkov(int[] notes, double[][] matrix){
		this();
		this.map = notes;
		this.markovMatrix = matrix;
	}
	
	
	public int getNextPitch(int previousPitch) {
		int result = 0;
		boolean hasPrevPitch = false;
		
		if(previousPitch != 0){
			seed = MoMidiUtils.getIndex(map, previousPitch);
			hasPrevPitch = true;
		}
		
		if(isFirstTime && !hasPrevPitch){
			result = map[seed];
			isFirstTime = false;
		} else {
			// Retrieve a random number between 0.0 and 1.0
			double choice = Math.random();
			
			// The current sum of weightings left to right
			double currentSum = 0.0;
			
			while(output < markovMatrix.length){
				currentSum += markovMatrix[seed][output];
				if (choice <= currentSum) {
					break; // break when we have chosen the right number
				}
				output++;
//				if(output >= markovMatrix.length){
//					output = output - 1;
//				}
			}
			
//			// Check matrix left to right
//			for (; output < markovMatrix.length; output++) {
//				currentSum += markovMatrix[output][seed];
//				if (choice <= currentSum) {
//					break; // break when we have chosen the right number
//				}
//			}
			
			result = map[output];
			seed = output;
			output = 0;
		}
		
		return result;
	}
	

	public static void main(String[] args) {
		// Score, part and phrase to contain the output
//		Score scr = new Score();
//		Part part = new Part();
//		Phrase phrase = new Phrase();
	
		BasicMarkov bm = new BasicMarkov();
		System.out.println(bm.markovMatrix[4][0]);
		// Add the seed note to the phrase first
//		Note n = new Note();
//		n.setPitch(bm.getNextPitch(0));
//		phrase.addNote(n);
//	
//		// Generate notes and add them to a phrase
//		for (int i = 0; i < 30; i++) {
//			Note note = new Note();
//			note.setPitch(bm.getNextPitch(0));
//			phrase.addNote(note);
//		}
//		part.addPhrase(phrase);
//		scr.addPart(part);
//		Play.midi(scr);
	}
}
